/**
 * Matter 设备类型 BridgedDevice 基类
 */
#pragma once

#include "BasicInformation.h"
#include <app/util/attribute-storage.h>
#include "Message.h"

using namespace chip;

/**
 * \brief
 *    定义一个 `BridgedDevice` 的代理接口，来通知子设备的控制下发与状态变更消息
 */
class BridgedDeviceDelegate
{
public:
    virtual ~BridgedDeviceDelegate() = default;

    /**
     * \brief 子设备状态属性变更后调用此接口，通知 matter协议栈 变更设备属性
     */
    virtual void OnStatusChanged(app::ConcreteAttributePath* path) = 0;

    /**
     * \brief 子设备执行控制命令，需要向网关发送Mesh控制消息时调用此接口
     */
    virtual void OnMessageSend(DataBlock* block) = 0;

    virtual void OnGetRemoteAttribute(Path *path) = 0;
};


/**
 * \brief 桥接的子设备基类
 *   - BridgedDevice类负责实现 BridgedDeviceBasicCluster 与 DescriptorCluster 两个基础的 Cluster。
 *   - 提供子设备通用的方法如: NotifyStatusChanged、SendMeshMessage 供子类调用
 *   - 提供可重写的虚函数: ReadAttribute、WriteAttribute、OnReport 供子类重写差异化实现。
 */
class BridgedDevice
{
public:
    static constexpr uint16_t kDeviceTypeBridgedNode = 0x0013;
    static constexpr  chip::DeviceTypeId kInvalidDeviceType = 0xffff;
    explicit BridgedDevice(const BasicInformation* node);
    virtual ~BridgedDevice();

    bool IsReachable() { return mReachable; }
    void SetReachable(bool reachable);

    EndpointId GetEndpoint() { return mEndpointId; }
    void SetEndpoint(EndpointId endpoint) { mEndpointId = endpoint; }

    std::string GetName() { return mName; }
    void SetName(std::string name) { mName = name; }

    void SetParentEndpointId(EndpointId endpoint) { mParentEndpointId = endpoint; }
    EndpointId GetParentEndpointId() { return mParentEndpointId; }

    // 将设备加入到ember协议栈中
    virtual ChipError AttachToIndex(uint16_t index);
    // 读属性、写属性、子设备Mesh消息上报虚函数定义
    virtual Protocols::InteractionModel::Status ReadAttribute(ClusterId clusterId, AttributeId attributeId, uint8_t* buffer, uint16_t maxReadLength);
    virtual Protocols::InteractionModel::Status WriteAttribute(ClusterId clusterId, const EmberAfAttributeMetadata* attributeMetadata, uint8_t* buffer);
    virtual ChipError OnReport(const DataBlock * message);

    virtual ChipError OnReadAttributes();
    void GetRemoteAttribute(ClusterId clusterId, AttributeId attributeId) const;

    void SetDelegate(BridgedDeviceDelegate* instance);

protected:
    // 通知matter客户端，状态有变化
    void NotifyStatusChanged(ClusterId cluster, AttributeId attribute);
    // 向 Mesh NCP 端发送控制消息
    void SendMessage(DataBlock* block);

    std::vector<EmberAfCluster> mClusters;
    const BasicInformation* mInfo;
    std::string mName;

private:
    bool mReachable = true;
    EndpointId mEndpointId = 0;
    EndpointId mParentEndpointId = 0;

    EmberAfEndpointType mEndpointType{};
    std::vector<EmberAfDeviceType> mDeviceTypes;
    DataVersion *mClusterDataVersion = nullptr;

    BridgedDeviceDelegate* mDelegate = nullptr;
};
